;----------------------------------------------------
;
; Rotate.ASM
;
; Sample Custom Command Program.
; Written by CTG
;
;
;
;----------------------------------------------------


ASSUME CS:CODE, ES:NOTHING, SS:NOTHING, DS:CODE

code segment para public 'code'
include Custom.inc

org	100h
Start:		mov	CS:HostDataSeg,ds
		jmp	SkipOverData

HostDataSeg	dw	0
CharToRotate	dw	0

InstructTxt	db	'Click outside the main window',0dh
		db	'or press ESC to exit ROTATE',0
InstructLen	equ	$-InstructTxt



SkipOverData:	test	DS:[EditFlag],-1
		jz	QuickExit	;This is not for sprite mode.

		call	DisplayPromptText
		
		push	DS:[MousePtr]	;Save mouse cursor
		mov	DS:[MousePtr],4

		HCALL	ShowMouse	;We are going to use the mouse
WaitMouseLoop:
		mov	ah,1
		int	16h		;Is a key waiting?
		jz	NoKey

		xor	ah,ah
		int	16h		;Get the key
		cmp	al,27		;Was Escape pressed
		jz	Exit
NoKey:
		HCALL	GetMousePosition;Update mouse information
		
		test	DS:[Buttons],3	;Did the mouse click?
		jz	WaitMouseLoop

		MouseCheck	GotValidChar,0,0,247,15*8	;Click in window?
		
Exit:		HCALL	HideMouse	;Remove mouse from display
		pop	DS:[MousePtr]	;Restore mouse cursor
QuickExit:
		retf			;Program terminates.

;--------------------------------------------------------------
;
; GotValidChar:	User has clicked in the main window,
;		So figure out where on the map that position is
;		and rotate that character, then redraw everything.
;
;
;		We can calculate the map position with this formula.
;
;	   2*(	(MouseY/8+Yscroll)*MaxXChars+(MouseX/8+Xscroll)  )
;
;--------------------------------------------------------------

GotValidChar:	mov	ax,DS:[MouseY]	
		shr	ax,3			
		add	ax,DS:[YSCROLL]
		mul	DS:[MaxXChars]
		mov	bx,DS:[MouseX]
		shr	bx,3
		add	bx,DS:[XScroll]
		add	bx,ax
		shl	bx,1

		mov	DS,DS:[MDATA]		;Point to the map segment
		mov	ax,DS:[bx]		;Get the character under the mouse
		mov	ds,CS:HostDataSeg	;Restore data segment
		and	ax,DS:[CharacterMask]	;Mask off any flip bits etc.
		mov	CS:CharToRotate,ax	;Save this as the character to rotate

		call	RotateTheChar

		HCALL	HideMouse
		HCALL	DrawGalleryWindow	;Redraw anything that may have
		mov	DS:[EditIndex],0	;changed.
		HCALL	DrawEditBox
		mov	DS:[EditIndex],2
		HCALL	DrawEditBox
		mov	ax,CS:CharToRotate
		HCALL	DrawEntireScreenAX

		call	DebounceMouseButton	;Wait for the mouse to be release

		HCALL	ShowMouse

		jmp	WaitMouseLoop		;Do it again.


;-----------------------------------------------------

RotateTheChar:
		mov	si,CS:CharToRotate	;Get the character to rotate.
		mov	ax,ds
		mov	es,ax
		shl	si,5			;Point to the character data.
		mov	ds,DS:[CDATA]		;Get the character segment.
		mov	di,offset CharacterNorm
		mov	cx,16		
	    rep movsw				;Copied over to CharacterNorm
		mov	ds,CS:HostDataSeg

	    	call	RotateCharacterNorm	;Rotate CharacterNorm into CharacterH

		mov	si,offset CharacterH
		mov	es,DS:[CDATA]
		mov	di,CS:CharToRotate
		shl	di,5
		mov	cx,16
	    rep movsw				;Copy CharacterH back to Character segment

		mov	ax,ds			;Restore ES
		mov	es,ax

		ret

;---------------------------------------------------
;
; Rotates Character @ CharacterNorm and places it in CharacterH
;
; Rotates the character in four pixel pairs.  This is repeated
; 16 times over the face of the character. 
;  
;---------------------------------------------------

RotateCharacterNorm:
		mov	si,offset CharacterNorm
		mov	di,offset CharacterH+3
		mov	dh,4
NextCol:	mov	dl,4
		push	si
		push	di
NextRow:	mov	al,[si]
		mov	ah,[si+4]
		mov	bx,ax
		shr	bl,4
		and	bh,0f0h
		or	bh,bl
		mov	[di],bh

		shl	ah,4
		and	al,0fh
		or	al,ah
		mov	[di+4],al

		dec	di
		add	si,8
		dec	dl
		jnz	NextRow
		pop	di
		pop	si
		inc	si
		add	di,8
		dec	dh
		jnz	NextCol
		ret

;-----------------------------------------------------------------
;
; DisplayPromptText
;	Displays the text InstructTXT in a prompt box, and waits
;	for a user keypress or click.
;
;-----------------------------------------------------------------

DisplayPromptText:

		mov	ax,cs			;Copy local static into hosts 
		mov	ds,ax			;data segment.
		mov	di,offset CVALUES
		mov	cx,InstructLen
		mov	si,offset InstructTXT
	    rep movsw
		mov	DS,CS:HostDataSeg	;Restore data segment

		mov	DS:[PromptText],offset CVALUES
		mov	DS:[MaxInputLength],0
		HCALL	GetBoxedInput
		HCALL	DrawEntireScreen
		ret

;-----------------------------------------------------------------
;
;  DebounceMouseButton
;
;	Waits until the mouse is released.
;
;-----------------------------------------------------------------

DebounceMouseButton:
		HCALL	GetMousePosition
		test	DS:[Buttons],3
		jnz	DebounceMouseButton
		ret


code ends
end Start
